package com.livegoods.service.impl;

import com.livegoods.commons.pojo.LivegoodsResult;
import com.livegoods.pojo.House;
import com.livegoods.pojo.HouseES;
import com.livegoods.service.HouseService;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class HouseServiceImpl implements HouseService {

    @Autowired
    private ElasticsearchRestTemplate restTemplate;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public int init() {

        //查询出MongoDB的数据
        List<House> houses = mongoTemplate.findAll(House.class);

        List<IndexQuery> indexQueries = new ArrayList<>();


        int index = 0;
        for (House house : houses) {
            //创建HouseES对象
            HouseES houseES = new HouseES();
            //将House对象数据获取转换成HouseES对象
            houseES.setId(house.getId());
            houseES.setTitle(house.getTitle());
            houseES.setCity(house.getCity());
            houseES.setPrice("<h3>"+house.getPrice()+"</h3>");
            houseES.setRentType(house.getRentType());
            houseES.setImg(house.getImgs().get(0));
            //拼接houseType；ES中的houseType是有MongoDB中的多个数据拼接而成
            //houseES.setHouseType(house.getHouseType());
            String houseType = house.getInfo().get("level")+" | "+house.getInfo().get("type")+" - "+house.getHouseType();
            houseES.setHouseType(houseType);

            //将对象设置到IndexQuery中
            IndexQuery indexQuery = new IndexQuery();
            indexQuery.setObject(houseES);

            //t添加到集合
            indexQueries.add(indexQuery);
            index++;
        }
        //将HouseES对象数据存储到ES中: 批量插入
        restTemplate.bulkIndex(indexQueries);
        return index;
    }


    @Value("${livegoods.fastdfs.nginx}")
    private String nginx;

    @Override
    public LivegoodsResult search(String city, String keyword, int page, int size) {


        //城市条件
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("city", city);

        //关键字搜索
        MatchQueryBuilder matchQueryBuilder1 = QueryBuilders.matchQuery("title", keyword);

        //多条件混合查询
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must().add(matchQueryBuilder);
        boolQueryBuilder.must().add(matchQueryBuilder1);

        NativeSearchQueryBuilder searchQueryBuilder = new NativeSearchQueryBuilder();

        //设置条件
        searchQueryBuilder.withQuery(boolQueryBuilder);

        //设置分页
        searchQueryBuilder.withPageable(PageRequest.of(page,size));

        //创建高亮对象设置高亮信息
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("title");
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</span>");

        //设置高亮
        searchQueryBuilder.withHighlightBuilder(highlightBuilder);



        NativeSearchQuery searchQuery = searchQueryBuilder.build();

        AggregatedPage<HouseES> houseESAggregatedPage = restTemplate.queryForPage(searchQuery, HouseES.class, new SearchResultMapper() {
            @Override
            public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) {

                //获取查询结果
                SearchHit[] hits = searchResponse.getHits().getHits();


                List<HouseES> houseESList = new ArrayList<>();
                for (SearchHit hit : hits) {

                    //创建HouseES对象
                    HouseES houseES = new HouseES();
                    houseES.setId(hit.getId());
                    //获取普通Source源数据
                    Map<String, Object> sourceAsMap = hit.getSourceAsMap();

                    houseES.setCity(sourceAsMap.get("city").toString());
                    houseES.setHouseType(sourceAsMap.get("houseType").toString());
                    houseES.setImg(nginx+sourceAsMap.get("img").toString());
                    houseES.setRentType(sourceAsMap.get("rentType").toString());
                    houseES.setPrice(sourceAsMap.get("price").toString());
                    //获取高亮数据
                    Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                    if(highlightFields.containsKey("title")){

                        HighlightField highlightField = highlightFields.get("title");
                        Text[] fragments = highlightField.getFragments();
                        Text titleText = fragments[0];

                        //获取高亮数据
                        String title = titleText.toString();// "合租·墩<span style='color:red'>发</span>-"

                        houseES.setTitle(title);

                        houseESList.add(houseES);
                    }
                }
                //获取总数
                long total = searchResponse.getHits().totalHits;

                return new AggregatedPageImpl(houseESList,pageable,total);
            }

            @Override
            public <T> T mapSearchHit(SearchHit searchHit, Class<T> aClass) {
                return null;
            }
        });


        //获取当前页结果集
        List<HouseES> houseESList = houseESAggregatedPage.getContent();




        LivegoodsResult ok = LivegoodsResult.ok(houseESList);



        //获取总页数
        int totalPages = houseESAggregatedPage.getTotalPages();
        //设置总页数
        ok.setTotalPage(totalPages);

        //如果当前页小于总页数，说明还可以分页
        if((page+1)<totalPages){
            ok.setHasMore(true);
        }


        return ok;
    }

}

/*
* {
  "took" : 85,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 1.1276041,
    "hits" : [
      {
        "_index" : "house_index",
        "_type" : "house_type",
        "_id" : "60612c1bc6220000a5001c04",
        "_score" : 1.1276041,
        "_source" : {
          "id" : "60612c1bc6220000a5001c04",
          "title" : "合租·墩发-北卧",
          "houseType" : "17/19层 | 一居室 - 30.97 ㎡",
          "price" : "<h3>null</h3>",
          "img" : "/group1/M00/00/00/rBEAA1_mpTWAfFePAAjIoXS-cuE112.png",
          "rentType" : "整租",
          "city" : "深圳"
        },
        "highlight" : {
          "title" : [
            "合租·墩<span style='color:red'>发</span>-"
          ]
        }
      }
    ]
  }
}

*
* */



